package com.yeyks.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeyks.account.dal.domain.AccountInfo;
import com.yeyks.common.appcommon.dto.order.AppAutoGrabOrderDTO;
import com.yeyks.common.appcommon.dto.order.AppGrabOrderDTO;
import com.yeyks.common.appcommon.param.order.AddGrabOrderParam;
import com.yeyks.common.appcommon.param.order.UpdateAutoGrabOrderParam;
import com.yeyks.common.appcommon.result.CommonResult;
import com.yeyks.common.dto.mq.EsUpdateMessage;
import com.yeyks.common.exception.OftenFiledException;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.common.result.OrderPickWebSocket;
import com.yeyks.common.utils.ObjectConvertUtil;
import com.yeyks.common.utils.apputil.bean.MyBeanUtils;
import com.yeyks.common.utils.apputil.redis.RedisService;
import com.yeyks.common.utils.apputil.rediskey.RedisKey;
import com.yeyks.commonReference.append.rocketmq.service.producer.MQProducerService;
import com.yeyks.commonReference.service.order.OrderPickRecordService;
import com.yeyks.hotel.dal.dao.HotelInfoMapper;
import com.yeyks.hotel.dal.domain.HotelInfo;
import com.yeyks.service.AppGrabOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author: dagny
 * @date: 2019/8/12 0012 15:52
 */
@Service
@Slf4j
public class AppGrabOrderServiceImpl implements AppGrabOrderService {


    @Autowired
    private RedisService redisService;
    @Autowired
    private OrderPickRecordService orderPickRecordService;
    @Autowired
    private HotelInfoMapper hotelInfoMapper;
    @Autowired
    private MQProducerService mqProducerService;


    @Override
    public CommonResult<List<AppGrabOrderDTO>> list(AccountInfo accountInfo) {


        List<AppGrabOrderDTO> grabOrderDTOList = Lists.newArrayList();
        List<Map> grabMap = redisService.getList((RedisKey.KEY + accountInfo.getId()));
        if (!CollectionUtils.isEmpty(grabMap)) {
            for (Map<String, Object> map : grabMap) {
                try {
                    AppGrabOrderDTO grabOrderDTO = ObjectConvertUtil.mapToBean(map, AppGrabOrderDTO.class);
                    //验证时间是否超时
                    if ((System.currentTimeMillis() - grabOrderDTO.getStartTime().getTime()) / 1000 > RedisKey.KEEP_TIME) {
                        //删除超时的数据
                        redisService.deleteHashString((RedisKey.KEY + accountInfo.getId()),
                                (RedisKey.HASH_KEY + (grabOrderDTO.getUserId() + ":" + grabOrderDTO.getTimestamp())));
                        continue;
                    }
                    grabOrderDTOList.add(grabOrderDTO);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return CommonResult.success(grabOrderDTOList);
    }

    @Override
    public CommonResult grabOrder(AddGrabOrderParam param, AccountInfo accountInfo) {

        Map<String, Object> grabMapDTO = redisService.getHashString((RedisKey.KEY + accountInfo.getId()),
                (RedisKey.HASH_KEY + (param.getUserId() + ":" + param.getTimestamp())));
        if (null != grabMapDTO && !grabMapDTO.isEmpty()) {
            try {
                AppGrabOrderDTO grabOrderDTO = ObjectConvertUtil.mapToBean(grabMapDTO, AppGrabOrderDTO.class);
                if (null == grabOrderDTO ||
                        ((System.currentTimeMillis() - grabOrderDTO.getStartTime().getTime()) / 1000 > RedisKey.KEEP_TIME)) {
                    return CommonResult.failed("抢单已经过期");
                }
                OrderPickWebSocket orderPickWebSocket = MyBeanUtils.convert(grabOrderDTO, OrderPickWebSocket.class);
                //执行抢单操作
                orderPickRecordService.robOrder(orderPickWebSocket);
                //抢单成功删除该条信息
                redisService.deleteHashString((RedisKey.KEY + accountInfo.getId()),
                        (RedisKey.HASH_KEY + (grabOrderDTO.getUserId() + ":" + grabOrderDTO.getTimestamp())));
                return CommonResult.success(null, "抢单成功！");
            } catch (ServiceException e) {
                //抛出自己的异常信息
                throw new OftenFiledException(e.getMessage());
            }
        }
        return CommonResult.failed("抢单已经过期");
    }

    @Override
    public CommonResult<AppAutoGrabOrderDTO> getAutoGrabOrder(AccountInfo accountInfo) {

//        List<HotelInfo> hotelInfoList = hotelInfoMapper.selectByOperator(accountInfo.getId());
//        if (!CollectionUtils.isEmpty(hotelInfoList)) {
            HotelInfo hotelInfo = hotelInfoMapper.selectByHotelManager(accountInfo.getId());
            if(null!=hotelInfo){
                AppAutoGrabOrderDTO autoGrabOrderDTO = new AppAutoGrabOrderDTO();
                autoGrabOrderDTO.setHotelId(hotelInfo.getId());
                autoGrabOrderDTO.setManualPickOrder(hotelInfo.getManualPickOrder());
                return CommonResult.success(autoGrabOrderDTO);
            }
        //}
        return CommonResult.failed("酒店信息有误");
    }

    @Override
    public CommonResult updateAutoGrabOrder(UpdateAutoGrabOrderParam param, AccountInfo accountInfo) {

        HotelInfo hotelInfo = hotelInfoMapper.selectById(param.getHotelId());
        if (null != hotelInfo) {
            if (hotelInfo.getManualPickOrder() == 1) {
                hotelInfo.setManualPickOrder(0);
            } else {
                hotelInfo.setManualPickOrder(1);
            }
            int count = hotelInfoMapper.updateById(hotelInfo);
            if (count > 0) {
                //更新ES的信息
                List<String> hotelIds = Lists.newArrayList();
                hotelIds.add(String.valueOf(param.getHotelId()));
                mqProducerService.sendEsUpdate(new EsUpdateMessage().setType("hotel").setSourceType("yyks")
                        .setSourceIds(hotelIds), 0);
                Map<String, Object> dataMap = Maps.newHashMap();
                dataMap.put("manualPickOrder", hotelInfo.getManualPickOrder());
                return CommonResult.success(dataMap, "更新是否自动抢单成功");
            }
        }
        return CommonResult.failed("酒店信息有误");
    }

    @Override
    public CommonResult<List<AppGrabOrderDTO>> newList(AccountInfo accountInfo) {

        List<AppGrabOrderDTO> grabOrderDTOList = Lists.newArrayList();
        List<Map> grabMap = redisService.getList((RedisKey.KEY + accountInfo.getId()));
        if (!CollectionUtils.isEmpty(grabMap)) {
            for (Map<String, Object> map : grabMap) {
                try {
                    AppGrabOrderDTO grabOrderDTO = ObjectConvertUtil.mapToBean(map, AppGrabOrderDTO.class);
                    //验证时间是否超时
                    if(null != grabOrderDTO){
                        if (((System.currentTimeMillis() - grabOrderDTO.getStartTime().getTime()) / 1000 > RedisKey.KEEP_TIME
                                && grabOrderDTO.getStatus() == 0)) {
                            //删除超时的数据
                            redisService.deleteHashString((RedisKey.KEY + accountInfo.getId()),
                                    (RedisKey.HASH_KEY + (grabOrderDTO.getUserId() + ":" + grabOrderDTO.getTimestamp())));
                            continue;
                        }else if((System.currentTimeMillis() - grabOrderDTO.getStartTime().getTime()) / 1000 > (8 * 60)){
                            //删除超过8分钟的数据的数据
                            redisService.deleteHashString((RedisKey.KEY + accountInfo.getId()),
                                    (RedisKey.HASH_KEY + (grabOrderDTO.getUserId() + ":" + grabOrderDTO.getTimestamp())));
                            continue;
                        }
                    }
                    grabOrderDTOList.add(grabOrderDTO);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(!CollectionUtils.isEmpty(grabOrderDTOList)){
                grabOrderDTOList = grabOrderDTOList.stream().sorted(Comparator.comparing(AppGrabOrderDTO::getStartTime).reversed())
                        .collect(Collectors.toList());
            }
        }

        return CommonResult.success(grabOrderDTOList);
    }

    @Override
    public CommonResult grabNewOrder(AddGrabOrderParam param, AccountInfo accountInfo) {

        Map<String, Object> grabMapDTO = redisService.getHashString((RedisKey.KEY + accountInfo.getId()),
                (RedisKey.HASH_KEY + (param.getUserId() + ":" + param.getTimestamp())));
        if (null != grabMapDTO && !grabMapDTO.isEmpty()) {
            try {
                AppGrabOrderDTO grabOrderDTO = ObjectConvertUtil.mapToBean(grabMapDTO, AppGrabOrderDTO.class);

                if (null == grabOrderDTO ||
                        ((System.currentTimeMillis() - grabOrderDTO.getStartTime().getTime()) / 1000 > RedisKey.KEEP_TIME)) {
                    return CommonResult.failed("抢单已经过期");
                }
                OrderPickWebSocket orderPickWebSocket = MyBeanUtils.convert(grabOrderDTO, OrderPickWebSocket.class);
                //执行抢单操作
                orderPickRecordService.robOrder(orderPickWebSocket);
                grabOrderDTO.setStatus(1);
                //重新设置已抢单的数据信息
                redisService.saveHashString(ObjectConvertUtil.objectToMap(grabOrderDTO),
                        (RedisKey.KEY + accountInfo.getId()),
                        (RedisKey.HASH_KEY + (grabOrderDTO.getUserId() + ":" + grabOrderDTO.getTimestamp())),
                        8,
                        TimeUnit.MINUTES);
                return CommonResult.success(null, "抢单成功！");
            } catch (ServiceException e) {
                //抛出自己的异常信息
                throw new OftenFiledException(e.getMessage());
            }
        }
        return CommonResult.failed("抢单已经过期");
    }

}
